package cn.jingyuan.bee.utils;

import cn.jingyuan.bee.utils.lang.ObjectId;
import cn.jingyuan.bee.utils.lang.Singleton;
import cn.jingyuan.bee.utils.lang.Snowflake;
import cn.jingyuan.bee.utils.lang.UUID;

/**
 * ID 生成器工具类，此工具类中主要封装：
 *
 * <pre>
 * 1. 唯一性 ID 生成器：UUID、ObjectId（MongoDB）、Snowflake
 * </pre>
 *
 * <p>
 * ID 相关文章见：http://calvin1978.blogcn.com/articles/uuid.html
 */
public class IdUtils {

    /**
     * 获取随机 UUID
     *
     * @return 随机 UUID
     */
    public static String random() {
        return UUID.randomUUID().toString();
    }

    /**
     * 简化的 UUID，去掉了横线
     *
     * @return 简化的 UUID，去掉了横线
     */
    public static String simple() {
        return UUID.randomUUID().toString(true);
    }

    /**
     * 获取随机 UUID，使用性能更好的 ThreadLocalRandom 生成 UUID
     *
     * @return 随机 UUID
     */
    public static String fast() {
        return UUID.fastUUID().toString();
    }

    /**
     * 简化的 UUID，去掉了横线，使用性能更好的 ThreadLocalRandom 生成 UUID
     *
     * @return 简化的 UUID，去掉了横线
     */
    public static String fastSimple() {
        return UUID.fastUUID().toString(true);
    }

    /**
     * 创建 MongoDB ID 生成策略实现<br>
     * ObjectId 由以下几部分组成：
     *
     * <pre>
     * 1. Time 时间戳
     * 2. Machine 所在主机的唯一标识符，一般是机器主机名的散列值
     * 3. PID 进程 ID，确保同一机器中不冲突
     * 4. INC 自增计数器，确保同一秒内产生 objectId 的唯一性
     * </pre>
     * <p>
     * 参考：http://blog.csdn.net/qxc1281/article/details/54021882
     *
     * @return ObjectId
     */
    public static String objectId() {
        return ObjectId.next();
    }

    /**
     * 创建 Twitter 的 Snowflake 算法生成器<br>
     * 分布式系统中，有一些需要使用全局唯一 ID 的场景，有些时候我们希望能使用一种简单一些的 ID，并且希望 ID 能够按照时间有序生成。
     *
     * <p>
     * snowflake 的结构如下(每部分用-分开):<br>
     *
     * <pre>
     * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
     * </pre>
     * <p>
     * 第一位为未使用，接下来的 41 位为毫秒级时间(41 位的长度可以使用 69 年)<br>
     * 然后是 5 位 dataCenterId 和 5 位 workerId(10 位的长度最多支持部署 1024 个节点）<br>
     * 最后 12 位是毫秒内的计数（12 位的计数顺序号支持每个节点每毫秒产生 4096 个 ID 序号）
     *
     * <p>
     * 参考：http://www.cnblogs.com/relucent/p/4955340.html
     *
     * @param workerId 终端 ID
     * @param dataCenterId 数据中心 ID
     *
     * @return {@link Snowflake}
     */
    public static Snowflake createSnowflake(long workerId, long dataCenterId) {
        return new Snowflake(workerId, dataCenterId);
    }

    /**
     * 获取单例的 Twitter 的 Snowflake 算法生成器对象<br>
     * 分布式系统中，有一些需要使用全局唯一 ID 的场景，有些时候我们希望能使用一种简单一些的 ID，并且希望 ID 能够按照时间有序生成。
     *
     * <p>
     * snowflake 的结构如下(每部分用-分开):<br>
     *
     * <pre>
     * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
     * </pre>
     * <p>
     * 第一位为未使用，接下来的 41 位为毫秒级时间(41 位的长度可以使用 69 年)<br>
     * 然后是 5 位 dataCenterId 和 5 位 workerId(10 位的长度最多支持部署 1024 个节点）<br>
     * 最后 12 位是毫秒内的计数（12 位的计数顺序号支持每个节点每毫秒产生 4096 个 ID 序号）
     *
     * <p>
     * 参考：http://www.cnblogs.com/relucent/p/4955340.html
     *
     * @param workerId 终端 ID
     * @param dataCenterId 数据中心 ID
     *
     * @return {@link Snowflake}
     */
    public static Snowflake getSnowflake(long workerId, long dataCenterId) {
        return Singleton.get(Snowflake.class, workerId, dataCenterId);
    }

}
